#pragma once

#include "mode.hpp"
#include "modeExit.hpp"

#include "qbe/src/ecs/bus.hpp"

namespace qbe::state {

struct AxxModel {};
struct BxxModel {};

struct State {
  State(ecs::Query _query, ecs::Bus& _bus);

  DrawingModeType getDrawingMode() const;
  EditingModeType getEditingMode() const;
  SelectModeType getSelectMode() const;

  bool switchMode(EditingChildMode mode);
  EditingChildMode getEditingChildMode() const;

  bool switchMode(AutoRouteFixedDistanceStretchLineChildMode mode);
  AutoRouteFixedDistanceStretchLineChildMode getAutoRouteFixedDistanceStretchLineChildMode() const;

  void addExitCall(DrawingModeType mode, const ExitCallback& ecb);
  void addExitCall(EditingModeType mode, const ExitCallback& ecb);
  void addExitCall(SelectModeType mode, const ExitCallback& ecb);

  void cjExitCall(const ExitCallback& ecb);

  bool switchMode(AllModeType _type, bool flushUi = true);

  bool switchMode(DrawingModeType _type, bool flushUi = true);
  bool switchMode(EditingModeType _type, bool flushUi = true);
  bool switchMode(SelectModeType _type, bool flushUi = true);

  bool exit(bool flushUi = true);
  void reset(bool flushUi = true);

  // 吸附
  bool isAdsorption();
  void setAdsorption(bool value, bool flushUi = false);

  // 斜角吸附
  bool isAngleTheAdsorption();
  void setAngleTheAdsorption(bool value);

  // 角度锁定
  bool isAngleLocking();
  void setAngleLocking(bool value);

  // 格点吸附精度
  double getAbsorbPrecision();
  void setAbsorbPrecision(double value);

  bool getCurrentLayer(uint32_t& layer);
  bool haveLayer(uint32_t layer);

  // 内部使用
  void setCurrentLayer(bool haveLayer);
  void setCurrentLayer(uint32_t layer);

  void onlyRead(bool value);

 private:
  ecs::Query query;
  ecs::Bus& bus;

  DrawingModeType drawingMode;
  EditingModeType editingMode;
  SelectModeType selectMode;
  EditingChildMode editingChildMode;
  AutoRouteFixedDistanceStretchLineChildMode autoRouteFixedDisStretchChildMode;

  SelectModeType exitSelectMode;

  ModeExitManager exitManager;

  static bool adsorption;
  static bool angleTheAdsorption;
  static bool angleLocking;

  double precision = 0;

  bool have_layer = false;
  uint32_t curren_layer = 0;

  bool only_read = false;
};

}  // namespace qbe::state